#include "ImgViewWidget.h"
#include <QtCore/QFile>
#include <QtGui/QImageReader>
#include <QtGui/QPainter>
#include <QtGui/QPaintEvent>
#include <QtCore/QDebug>
#include <QtGui/QApplication>
#include <QtGui/QMenu>
#include <QtCore/QFileInfo>
#include "Utility.h"

ImgViewWidget::ImgViewWidget(QWidget *parent)
	: QWidget(parent),_imgFileName(),_rotateAngle(0),_isZoomToWin(true),_xOffset(0),_yOffset(0),_zoomCount(1)
{
}

ImgViewWidget::~ImgViewWidget()
{

}

void ImgViewWidget::setImageFile(const QString& fileName){
	if (!this->isVisible())
		return;

	if (_imgFileName==fileName)
		return;

	if (!QFile::exists(fileName))
		return ;

	_imgFileName=fileName;
	zoomWindowSize();
}

void ImgViewWidget::mouseDoubleClickEvent ( QMouseEvent * event ){
	QWidget::mouseDoubleClickEvent(event);
	emit doubleClicked();
}

void ImgViewWidget::paintEvent ( QPaintEvent * event ){
	QWidget::paintEvent(event);
	if (_image.isNull())
		return ;

	QRect evtRect(event->rect());
	QPainter p(this);
	p.save();
	if (_isZoomToWin){
		if (_image.width()<this->width()){
			//center 
			p.translate((this->width()-_image.width())/2,0);
		}
		if (_image.height()<this->height()){
			//center 
			p.translate(0,(this->height()-_image.height())/2);
		}
		p.rotate(_rotateAngle);
		p.drawImage(event->rect(),_image,event->rect());
		p.drawRect(_image.rect());
	}else{
		//p.translate(_lstXOffset+_xOffset,_lstYOffset+_yOffset);
		p.rotate(_rotateAngle);
		p.drawImage(event->rect(),_image,
			event->rect().adjusted(-(_lstXOffset+_xOffset),-(_lstYOffset+_yOffset),
												-(_lstXOffset+_xOffset),-(_lstYOffset+_yOffset)));

		p.drawRect(_image.rect().adjusted(_lstXOffset+_xOffset,_lstYOffset+_yOffset,
												_lstXOffset+_xOffset,_lstYOffset+_yOffset));
	}
	p.restore();
	if (_isZoomToWin)
		drawImageInfo(p);
}

void ImgViewWidget::drawImageInfo(QPainter& p){
	if (_mousePressPoint.isNull() ){
		return ;
	}
#ifndef Q_NO_SURSOR
	QApplication::setOverrideCursor(Qt::WaitCursor);
#endif

	QImageReader imgReader(_imgFileName);
	QSize imgSize=imgReader.size ();
	QString info=QString("%1\n(%2x%3)")
						.arg(QFileInfo(_imgFileName).fileName ())
						.arg(imgSize.width())
						.arg(imgSize.height())
						;
	p.setBackground(Qt::black);
	p.setPen(Qt::white);
	p.setBackgroundMode(Qt::OpaqueMode);
	p.drawText(this->contentsRect(),Qt::AlignTop|Qt::AlignHCenter,info);
	
#ifndef Q_NO_SURSOR
	QApplication::restoreOverrideCursor ();
#endif	
}

void ImgViewWidget::zoomIn(){
#ifndef Q_NO_SURSOR
	QApplication::setOverrideCursor(Qt::WaitCursor);
#endif
	QImageReader imgReader(_imgFileName);
	QSize imgSize(imgReader.size());
	QSize mySize=this->size();

	if (imgSize.isValid() && imgSize.width()>mySize.width()){
		int ratio=(imgSize.width()-mySize.width())/5;
		int width=mySize.width()+_zoomCount*ratio;
		int height=width*mySize.height()/mySize.width();
		int newWidth,newHeight;
		if (width<=imgSize.width() && height<=imgSize.height()){
			newWidth=width;
			newHeight=height;
			_isZoomToWin=false;
			_xOffset=0;
			_yOffset=0;
			_lstXOffset=0;
			_lstYOffset=0;
			++_zoomCount;
		}else{
			newWidth=imgSize.width();
			newHeight=imgSize.height();
		}
		imgSize.scale(width,height,Qt::KeepAspectRatio);
		imgReader.setScaledSize(imgSize);
	}
	QImage img=imgReader.read();
	setUpdatesEnabled(false);
	if (!img.isNull()){
		_image=img;
	}else{
		static QImage failedImg(":/imgs/failed.PNG");
		qDebug()<<"Fail to load image "<<_imgFileName<<":"<<imgReader.errorString ()<<"\n";
		_imgFileName="";
		_image=failedImg;
	}
	setUpdatesEnabled(true);
#ifndef Q_NO_SURSOR
	QApplication::restoreOverrideCursor ();
#endif	
}

void ImgViewWidget::zoomOut(){
#ifndef Q_NO_SURSOR
	QApplication::setOverrideCursor(Qt::WaitCursor);
#endif
	QImageReader imgReader(_imgFileName);
	QSize imgSize(imgReader.size());
	QSize mySize=this->size();

	if (imgSize.isValid() && imgSize.width()>mySize.width()){
		int ratio=(imgSize.width()-mySize.width())/5;
		int width=mySize.width()+(_zoomCount-2)*ratio;
		int height=width*mySize.height()/mySize.width();
		int newWidth,newHeight;
		if (width>=mySize.width() && height>=mySize.height()){
			newWidth=width;
			newHeight=height;
			--_zoomCount;
			_isZoomToWin=false;
			_xOffset=0;
			_yOffset=0;
			_lstXOffset=0;
			_lstYOffset=0;
		}else{
			newWidth=imgSize.width();
			newHeight=imgSize.height();
			_isZoomToWin=true;
		}
		imgSize.scale(width,height,Qt::KeepAspectRatio);
		imgReader.setScaledSize(imgSize);
	}
	QImage img=imgReader.read();
	setUpdatesEnabled(false);
	if (!img.isNull()){
		_image=img;
	}else{
		static QImage failedImg(":/imgs/failed.PNG");
		qDebug()<<"Fail to load image "<<_imgFileName<<":"<<imgReader.errorString ()<<"\n";
		_imgFileName="";
		_image=failedImg;
	}
	setUpdatesEnabled(true);
#ifndef Q_NO_SURSOR
	QApplication::restoreOverrideCursor ();
#endif	
}

void ImgViewWidget::loadImageFile(){
#ifndef Q_NO_SURSOR
	QApplication::setOverrideCursor(Qt::WaitCursor);
#endif
	QImageReader imgReader(_imgFileName);
	if (_isZoomToWin){
		QSize imgSize(imgReader.size());
		if (imgSize.isValid()){
			QSize mySize=this->size();
			if (mySize.width()<imgSize.width() || mySize.height()<imgSize.height() ){
				imgSize.scale(mySize,Qt::KeepAspectRatio);
				imgReader.setScaledSize(imgSize);
				int quality=Utility::areaOfSize(imgSize)*75/Utility::areaOfSize(imgReader.size());
				imgReader.setQuality(quality+1);
				qDebug()<<"Use quality "<<quality+1<<"\n";
			}
		}
	}
	QImage img=imgReader.read();
	setUpdatesEnabled(false);
	if (!img.isNull()){
		_image=img;
	}else{
		static QImage failedImg(":/imgs/failed.PNG");
		qDebug()<<"Fail to load image "<<_imgFileName<<":"<<imgReader.errorString ()<<"\n";
		_imgFileName="";
		_image=failedImg;
	}
	setUpdatesEnabled(true);
#ifndef Q_NO_SURSOR
	QApplication::restoreOverrideCursor ();
#endif	
}


void ImgViewWidget::zoomOriginalSize(){
	_isZoomToWin=false;
	_xOffset=0;
	_yOffset=0;
	_lstXOffset=0;
	_lstYOffset=0;
	loadImageFile();
}

void ImgViewWidget::zoomWindowSize(){
	_isZoomToWin=true;
	loadImageFile();
}

void ImgViewWidget::mousePressEvent ( QMouseEvent * event ) {
	QWidget::mousePressEvent(event);

	if (!_isZoomToWin){
		_xOffset=0;
		_yOffset=0;
	}
	_mousePressPoint=event->pos();
	update();
}

void ImgViewWidget::mouseReleaseEvent ( QMouseEvent * event ) {
	QWidget::mouseReleaseEvent(event);
	if (_mousePressPoint.isNull())
		return ;

	if (_isZoomToWin){
		QPoint pos=event->pos();
		if (_mousePressPoint.x()-pos.x()>5){
			emit leftMouseMoved();
		}else if (pos.x()-_mousePressPoint.x()>5){
			emit rightMouseMoved();
		}
	}else{
		_lstXOffset+=_xOffset;
		_lstYOffset+=_yOffset;
		_xOffset=0;
		_yOffset=0;
	}
	_mousePressPoint=QPoint();
	update();
}

void ImgViewWidget::mouseMoveEvent ( QMouseEvent * event ){
	if (!_isZoomToWin){
		_xOffset=event->pos().x()-_mousePressPoint.x();
		_yOffset=event->pos().y()-_mousePressPoint.y();
		update();
	}
}

void ImgViewWidget::rotateRight(){
	_rotateAngle+=90;
	update();
}

void ImgViewWidget::rotateLeft(){
	_rotateAngle-=90;
	update();
}
